MySQL CSV डेटा से पूर्ण मान लोड करता है


167

मेरे पास एक फ़ाइल है जिसमें संख्यात्मक मानों के 3 से 4 कॉलम हो सकते हैं जो अल्पविराम द्वारा अलग किए जाते हैं। जब वे पंक्ति के अंत में होते हैं, तो खाली फ़ील्ड को अपवाद के साथ परिभाषित किया जाता है:

1,2,3,4,5
1,2,3,,5
1,2,3

निम्न तालिका MySQL में बनाई गई थी:

+ ------- + -------- + ------ + ----- + --------- + ------- +
| फील्ड | प्रकार | नल | कुंजी | डिफ़ॉल्ट | अतिरिक्त |
+ ------- + -------- + ------ + ----- + --------- + ------- +
| एक | int (1) | हाँ | | नल | |
| दो | int (1) | हाँ | | नल | |
| तीन | int (1) | हाँ | | नल | |
| चार | int (1) | हाँ | | नल | |
| पांच | int (1) | हाँ | | नल | |
+ ------- + -------- + ------ + ----- + --------- + ------- +

मैं MySQL LOAD कमांड का उपयोग करके डेटा लोड करने का प्रयास कर रहा हूं:

LOAD DATA INFILE '/tmp/testdata.txt' INTO TABLE moo FIELDS 
TERMINATED BY "," LINES TERMINATED BY "\n";

परिणामी तालिका:

+ ------ + ------ + ------- + ------ + ------ +
| एक | दो | तीन | चार | पांच |
+ ------ + ------ + ------- + ------ + ------ +
| 1 | 2 | 3 | 4 | 5 |
| 1 | 2 | 3 | 0 | 5 |
| 1 | 2 | 3 | नल | नल |
+ ------ + ------ + ------- + ------ + ------ +

समस्या इस तथ्य के साथ है कि जब कोई फ़ील्ड कच्चे डेटा में खाली होती है और परिभाषित नहीं होती है, तो किसी कारण से MySQL कॉलम डिफ़ॉल्ट मान (जो NULL है) का उपयोग नहीं करता है और शून्य का उपयोग करता है। जब फ़ील्ड पूरी तरह से अनुपलब्ध है, तो NULL का सही उपयोग किया जाता है।

दुर्भाग्य से, मुझे इस स्तर पर NULL और 0 के बीच अंतर करने में सक्षम होना है, इसलिए किसी भी मदद की सराहना की जाएगी।

धन्यवाद एस।

संपादित करें

SHOW WARNINGS का उत्पादन:

+ --------- + ------ + -------------------------------- ------------------------ +
| स्तर | कोड | संदेश |
+ --------- + ------ + -------------------------------- ------------------------ +
| चेतावनी | 1366 | गलत पूर्णांक मान: पंक्ति 2 पर कॉलम 'चार' के लिए |
| चेतावनी | 1261 | पंक्ति 3 में सभी स्तंभों का डेटा नहीं है |
| चेतावनी | 1261 | पंक्ति 3 में सभी स्तंभों का डेटा नहीं है |
+ --------- + ------ + -------------------------------- ------------------------ +

डेटा स्कीमा परिवर्तन के साथ, मैं d6tstack का उपयोग करूंगा जो चलने से पहले सभी कॉलम संरेखित करता है LOAD DATA। डेटा स्कीमा परिवर्तन पर d6tstack SQL उदाहरण अनुभाग देखें ।
शहरनॉर्मन

जवाबों:


193

यह वही करेगा जो आप चाहते हैं। यह चौथे चर को एक स्थानीय चर में पढ़ता है, और फिर वास्तविक क्षेत्र मान को NULL में सेट करता है, यदि स्थानीय चर समाप्त होता है, जिसमें रिक्त स्थान शामिल है:

LOAD DATA INFILE '/tmp/testdata.txt'
INTO TABLE moo
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
(one, two, three, @vfour, five)
SET four = NULLIF(@vfour,'')
;

यदि वे सभी संभवतः खाली हैं, तो आप उन सभी को चर में पढ़ेंगे और इस तरह के कई सेट स्टेटमेंट होंगे:

LOAD DATA INFILE '/tmp/testdata.txt'
INTO TABLE moo
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
(@vone, @vtwo, @vthree, @vfour, @vfive)
SET
one = NULLIF(@vone,''),
two = NULLIF(@vtwo,''),
three = NULLIF(@vthree,''),
four = NULLIF(@vfour,'')
;

सैद्धांतिक रूप से, मुझे लगता है - लेकिन यह सब-इन-मेमोरी है, और प्रति पंक्ति में केवल थोड़ी मात्रा में डेटा पकड़े हुए है, इसलिए मैं छवि देता हूं कि यह असीम होगा; लेकिन आपको इसका परीक्षण करना चाहिए अगर आपको लगता है कि यह एक समस्या हो सकती है।
डंकन लॉक

4
मुझे वास्तव में यह उत्तर पसंद है। उपयोगकर्ता एक्सेल के लिए ''एक सीएसवी ( क्वेरी IFNULL(Col,'')में उपयोग करते हुए SELECT INTO OUTFILE) डाउनलोड करते समय खाली तार देख सकते हैं लेकिन फिर अपलोड उन्हें \Nसीएसवी से निपटने के लिए शून्य बनाम के रूप में स्वीकार करते हैं । धन्यवाद!
क्रिस

9
मैंने जिन तारीखों के लिए 'NULLIF (STR_TO_DATE (@ date1, "% d /% m /% Y"), "0000-00-00" का उपयोग किया था)
Joaquín L. Robles

1
मेरे पास एक सीएसवी फाइल है जिसमें शून्य है 0जिसे परिवर्तित किया जाना चाहिए NULL(क्योंकि प्रश्न में डेटा के लिए शून्य मान होना संभव नहीं है) और खाली तार भी। कैसे सुनिश्चित करें कि शून्य और खाली तार दोनों में परिवर्तित हो गए हैं NULL?
पॉल रौजीक्स

यदि शून्य मान और खाली स्ट्रिंग्स अलग-अलग कॉलम में हैं, तो बस खाली स्ट्रिंग्स के लिए उपरोक्त करें, और शून्य के लिए कुछ इस तरह से करें nullif(@vone, 0):।
डंकन लॉक

136

MySQL मैनुअल कहता है:

LOAD DATA INFILE के साथ डेटा पढ़ते समय, खाली या गायब कॉलम को '' के साथ अपडेट किया जाता है। यदि आप किसी कॉलम में NULL मान चाहते हैं, तो आपको डेटा फ़ाइल में \ N का उपयोग करना चाहिए। शाब्दिक शब्द "NULL" का उपयोग कुछ परिस्थितियों में भी किया जा सकता है।

तो आपको इस तरह से रिक्त स्थान को \ N से बदलना होगा:

1,2,3,4,5
1,2,3,\N,5
1,2,3

3
टिप के लिए धन्यवाद - मैं कच्चे स्रोत डेटा को संपादित करने के लिए उलझन में हूं, लेकिन अगर यह एकमात्र तरीका है, तो मैं इसे बाहर की कोशिश करूंगा।
स्पिरोस

7
मैं आपके संदेह को समझता हूं, कोई भी कच्चे डेटा को संपादित करना पसंद नहीं करता है, यह सिर्फ सही नहीं लगता है। हालाँकि, यदि आप इसके बारे में एक मिनट के लिए सोचते हैं, तो NULL और खाली स्ट्रिंग के बीच अंतर करने का एक तरीका होना चाहिए। रिक्त प्रविष्टियों को NULLs में अनुवादित किया जाना चाहिए, आपको खाली स्ट्रिंग के लिए एक विशेष अनुक्रम की आवश्यकता होगी। यह अच्छा एक तरह से कैसे MySQL बताओ कैसे खाली प्रविष्टियों हालांकि, जांच टेबल मू TREAT कारतूस नल डेटा लोड INFILE '/tmp/testdata.txt' की तरह कुछ के इलाज के लिए करने के लिए होगा ...
Janci

2
ठीक है, लेकिन अगर आपके पास Fields enclosed by: "जो है "\N"की"name",\N,"stuff"
जोनाथन

3
मैं यह सत्यापित कर सकता हूं कि कम से कम "phpMyAdmin 3.5.5" के लिए कोई भी शैली \Ndenoting के रूप में स्वीकार नहीं की गई है NULL। इसके बजाय NULL, इस उदाहरण में उपयोग करें:"name","age",NULL,"other","stuff"
जोनाथन

1
हमारे पास MySQL 5.5.46-0 + deb8u1 है। मैंने NULL और \ N दोनों की कोशिश की, और only \ N ने हमारे लिए काम किया।
राफेल 75

6

डेटाबेस कॉन्फ़िगरेशन के आधार पर व्यवहार भिन्न होता है। सख्त मोड में यह एक और त्रुटि एक चेतावनी को फेंक देगा। डेटाबेस कॉन्फ़िगरेशन की पहचान के लिए निम्नलिखित क्वेरी का उपयोग किया जा सकता है।

mysql> show variables like 'sql_mode';

धन्यवाद! मैं अपने सिर को खरोंचने की कोशिश कर रहा था कि क्यों मैं खाली कॉलम के साथ एक सीएसवी आयात कर रहा हूं जिसे मैं सफलतापूर्वक उत्पादन सर्वर पर आयात कर रहा हूं कल मेरे ब्रांड-नए स्थानीय इंस्टॉलेशन पर काम नहीं कर रहा था - यह मेरे मामले में जवाब था!
एमा

3

रिक्त प्रविष्टियों को \ N से बदलने के लिए अपने इनपुट CSV को प्रीप्रोसेस करें।

Regex पर प्रयास करें: s / ,, /, \ n, / g और s /, $ /, \ N / g

सौभाग्य।


1
यह रेगेक्स आंशिक रूप से काम करता है, यह अनुक्रमिक रिक्त प्रविष्टियों को हल नहीं करता है, उदाहरण के लिए ,,,, \ n, \ n होगा, यदि आप इसे दो बार चलाते हैं, तो उपयोगी होना चाहिए
ivegen

1
उत्तर और पिछली टिप्पणी को संक्षेप में प्रस्तुत करेंगे। मेरे लिए काम करने के बाद, क्रम में: sed -i 's /, /, \ N / g' $ फ़ाइल, sed -i 's / ,,, / g' $ फ़ाइल, sed -i 's / \ एन, $ / \ N / g '$ फ़ाइल,
उमर खज़ामोव

मैं ऐसा करना चाहूंगा, लेकिन मैं इस बात पर स्पष्ट नहीं हूं कि आप इस रेगेक्स को कैसे चला रहे हैं। यदि आप फ़ाइल के विरुद्ध इसे चलाने के लिए MySQL का उपयोग कर रहे हैं तो यह सबसे अच्छा समाधान होगा। लेकिन आप यह नहीं कहते हैं और मैं समय का एक समूह खर्च नहीं करना चाहता कि कैसे कुछ ऐसा करना संभव नहीं है।
गधाकी जोंग

1

(variable1, @ variable2, ..) SET variable2 = nullif (@ वैरिएबल 2, '' या '') >> आप कोई भी शर्त रख सकते हैं


0

चर दिखाएं

Show variables like "`secure_file_priv`";

नोट: अपनी सीएसवी फ़ाइल को उपरोक्त कमांड द्वारा दिए गए स्थान पर रखें।

create table assessments (course_code varchar(5),batch_code varchar(7),id_assessment int, assessment_type varchar(10), date int , weight int);

नोट: यहां ' date' कॉलम में csv फ़ाइल के कुछ रिक्त मान हैं।

LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/assessments.csv' 
INTO TABLE assessments
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '' 
LINES TERMINATED BY '\n' 
IGNORE 1 ROWS 
(course_code,batch_code,id_assessment,assessment_type,@date,weight)
SET date = IF(@date = '', NULL, @date);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.